# 创建时间:2023/2/5 16:03
# 创建人:天霄
# 计划 :SenjoTwintail
# 文件 :common.py
# 基于 Python 3.8.2
# ========================================
# 不依赖项目的公共方法
# ========================================
import shutil
import yaml


def copy_file(from_path, to_path):
    """复制文件并重命名

    :param from_path: 原文件路径
    :param to_path: 新文件路径
    :return:
    """
    shutil.copy(from_path, to_path)


def get_yaml(file):
    """获取yaml数据

    :param file: yaml文件路径
    :return: yaml的所有数据
    """
    f = open(file, encoding="UTF-8")
    f_data = f.read()
    f.close()
    data = yaml.full_load(f_data)
    return data


def write_yaml(file, data):
    """写入yaml数据

    :param file: yaml文件路径
    :param data: 写入的数据
    """
    f = open(file, 'w', encoding='utf-8')
    yaml.dump(data, f, allow_unicode=True)
    f.close()


def return_dic(code, layer: str, msg: str, data=None):
    """定义响应格式，返回字典

    :param code: 响应码
    :param layer: 层次，如数据库层、接口层、业务层、实例层
    :param msg: 响应信息
    :param data: 响应数据，任意类型，默认空
    :return: dict
    """
    return {'code': code, 'layer': layer, 'msg': msg, 'data': data}


def tuple2str(tupledata: tuple) -> str:
    """根据传入的tuple转为sql适用的带括号的字符串

    :param tupledata: 元组数据
    :return:
    """
    if not tupledata:
        raise ValueError(f'必须传有效值！而传入的是【{tupledata}】')
    datatype = type(tupledata[0])
    if not all(list(map(lambda t: isinstance(t, datatype), tupledata))):
        raise ValueError(f'元组内的值类型不一致！元组为【{tupledata}】')
    if datatype is str:
        s = "','".join(tupledata)
        return f"('{s}')"
    elif datatype is int:
        s = ",".join(list(map(str, tupledata)))
        return f"({s})"
    else:
        raise ValueError(f'元组内的值类型只能为int或str！')


def next_strline(string, perline=10):
    """将一行文字自动换行"""
    if len(string) <= perline:
        return string
    return string[:perline] + '\n' + next_strline(string[perline:], perline)


def text2paragraph(long_text: str, length: int) -> list:
    """将多行长文本按指定长度分段

    :param long_text: 长文本，支持多行长文本
    :param length: 每段长度（2英文字符算作1长度）
    :return: [[],[]]分段后的文本list，一行一个list
    """
    leng = lambda s: 0.5 if len(s.encode('utf-8')) < 3 else 1
    '''2字节及以下算0.5单位长度，3字节及以上算1单位长度'''
    segments = list()
    pointStr = ('、', '，', '。', '：', '；', '！', '？', '）', '》', '】', '”')  # 允许附在行尾的标点符号
    for text in long_text.split('\n'):
        long = len(text)
        start_index, end_index = 0, 1
        shard_long = 0
        line = []
        for index, char in enumerate(text):
            shard_long += leng(char)
            # length-0.5、length且下一个长度为1，或length+0.5，或末尾字符则分段
            if index + 1 == long or shard_long > length or (shard_long in (length-0.5, length) and (
                    leng(text[index+1]) == 1 and text[index+1] not in pointStr)):
                line.append(text[start_index:end_index])
                shard_long = 0
                start_index = end_index
            end_index += 1
        segments.append(line)
    return segments

